#include "Sol9Math.h"
#include "Sol9Util.h"
#include "degree.h"
#include "radian.h"

namespace sol9
{
namespace core
{

	/// constructors
	degree::degree()
		: d(0.0f)
	{
	}

	degree::degree(f32 degrees)
		: d(0.0f)
	{
	}

	degree::degree(const degree& degrees)
		: d(degrees.d)
	{
	}

	degree::degree(const radian& radians)
		: d(radians.makeDegree())
	{
	}

	/// operators
	// -degree
	degree degree::operator-() const
	{
		return degree(-d);
	}

	// degree = value
	degree& degree::operator=(const f32& value)
	{
		d = value;
		return *this;
	}

	// degree = degree
	degree& degree::operator=(const degree& degrees)
	{
		d = degrees.d;
		return *this;
	}

	// degree = radian
	degree& degree::operator=(const radian& radians)
	{
		d = radians.makeDegree();
		return *this;
	}

	// degree + degree
	degree degree::operator+(const degree& degrees) const
	{
		return degree(d + degrees.d);
	}

	// degree + radian
	degree degree::operator+(const radian& radians) const
	{
		return radian(d + radians.makeDegree());
	}

	// degree += degree
	degree& degree::operator+=(const degree& degrees)
	{
		d += degrees.d;
		return *this;
	}

	// degree += radian
	degree& degree::operator+=(const radian& radians)
	{
		d += radians.makeDegree();
		return *this;
	}

	// degree - degree
	degree degree::operator-(const degree& degrees) const
	{
		return degree(d - degrees.d);
	}

	// degree - radian
	degree degree::operator-(const radian& radians) const
	{
		return degree(d - radians.makeDegree());
	}

	// degree -= degree
	degree& degree::operator-=(const degree& degrees)
	{
		d -= degrees.d;
		return *this;
	}

	// degree -= radian
	degree& degree::operator-=(const radian& radians)
	{
		d -= radians.makeDegree();
		return *this;
	}

	// degree * value
	degree degree::operator*(const f32& value) const
	{
		return degree(d * value);
	}

	// degree * radian
	degree degree::operator*(const degree& degrees) const
	{
		return degree(d * degrees.d);
	}

	// degree *= value
	degree& degree::operator*=(const f32& value)
	{
		d *= value;
		return *this;
	}

	// degree / value
	degree degree::operator/(const f32& value) const
	{
		if (core::isZero(value))
			return degree(d);

		return degree(d / value);
	}

	// degree /= value
	degree& degree::operator/=(const f32& value)
	{
		if (core::isZero(value))
			return *this;

		d /= value;
		return *this;
	}

	// degree < degree
	bool degree::operator<(const degree& degrees) const
	{
		return d < degrees.d;
	}

	// degree <= degree
	bool degree::operator<=(const degree& degrees) const
	{
		return (d < degrees.d) || (core::equals(d, degrees.d));
	}

	// degree > degree
	bool degree::operator>(const degree& degrees) const
	{
		return d > degrees.d;
	}

	// degree >= degree
	bool degree::operator>=(const degree& degrees) const
	{
		return (d > degrees.d) || (core::equals(d, degrees.d));
	}

	// degree == degree
	bool degree::operator==(const degree& degrees) const
	{
		return core::equals(d, degrees.d);
	}

	//// degree == radian
	//bool degree::operator==(const radian& radians) const
	//{
	//	return core::equals(d, radians.makeDegree());
	//}

	// degree != degree
	bool degree::operator!=(const degree& degrees) const
	{
		return !core::equals(d, degrees.d);
	}

	//// degree != radian
	//bool degree::operator!=(const radian& radians) const
	//{
	//	return !core::equals(d, radians.makeDegree());
	//}

	/// functions
	f32 degree::makeRadian() const
	{
		return core::deg2rad(d);
	}
		
} // namespace core
} // namespace sol9